# -*- coding: utf-8 -*-
'''
**********************************************************************
****************  smpy: Scientific Modelling in Python  **************
**********************************************************************
Copyright (c) 2013, Sergei Mingaleev (http://mingaleev.nanoscience.by)
All rights reserved.

Module "sys":
	Useful system level functions.
'''

# Some of the functions are based on the code from:
# http://code.activestate.com/recipes/511491/

def today():
	'''
	'''
	import datetime
	return datetime.datetime.ctime(datetime.datetime.today())

def get_registry_value(key, subkey, value):
	try:
		import winreg
	except ImportError:
		import _winreg as winreg
	key = getattr(winreg, key)
	handle = winreg.OpenKey(key, subkey)
	(value, type) = winreg.QueryValueEx(handle, value)
	return value

def python_version():
	import platform
	s = '{0} {1} {2} [{3}; {4}]'.format(platform.python_implementation(), platform.python_version(), platform.architecture()[0], platform.python_compiler(), platform.python_build()[1])
	return s

def os_version():
	def get(key):
		return get_registry_value(
			"HKEY_LOCAL_MACHINE", 
			"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
			key)
	os = get("ProductName")
	#TODO: "CSDVersion" is not always present (say, for 32bit python 
	# on 64bit system) - find a better way to check "Service Pack" number.
	try:
		sp = get("CSDVersion")
	except:
		sp = ''
	build = get("CurrentBuildNumber")
	return "%s %s (build %s)" % (os, sp, build)

def cpu_info():
	try:
		cputype = get_registry_value(
			"HKEY_LOCAL_MACHINE", 
			"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
			"ProcessorNameString")
		#TODO: add "cpuid" (also for except case), and start to use it.
		# Example of these two values:
		# cputype = "Intel(R) Core(TM)2 Duo CPU     E8500  @ 3.16GHz"
		# cpuid = "Intel64 Family 6 Model 23 Stepping 6"
		#cpuid = get_registry_value(
		#	"HKEY_LOCAL_MACHINE", 
		#	"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
		#	"Identifier")
	except:
		import wmi, pythoncom
		pythoncom.CoInitialize() 
		c = wmi.WMI()
		for i in c.Win32_Processor():
			cputype = i.Name
		pythoncom.CoUninitialize()

	if cputype == 'AMD Athlon(tm)':
		import wmi
		c = wmi.WMI()
		for i in c.Win32_Processor():
			cpuspeed = i.MaxClockSpeed
		cputype = 'AMD Athlon(tm) %.2f Ghz' % (cpuspeed / 1000.0)
	elif cputype == 'AMD Athlon(tm) Processor':
		import wmi
		c = wmi.WMI()
		for i in c.Win32_Processor():
			cpuspeed = i.MaxClockSpeed
		cputype = 'AMD Athlon(tm) %s' % cpuspeed
	else:
		pass
	return cputype


def hostname():
	try:
		import socket
		return socket.getfqdn()
	#try:
	#	return get_registry_value(
	#		"HKEY_LOCAL_MACHINE",
	#		'SYSTEM\\ControlSet001\\Control\\ComputerName\\ComputerName',
	#		'ComputerName')
	except:
		from platform import node
		compName = node
		return compName

def ram_total():
	'''
	Total physical RAM memory in bytes.
	'''
	import psutil
	return psutil.phymem_usage()[0]
 
def ram_free():
	'''
	Free physical RAM memory in bytes.
	'''
	import psutil
	return psutil.phymem_usage()[2]

def hdd_total(drive):
	'''
	Return the total size of a shared drive [bytes].
	Example:
		drive = r'\\servername\c$'
		print 'Total Size of %s = %d' % (drive, hdd_total(drive))
	'''
	import win32com.client
	try:
		fso = win32com.client.Dispatch("Scripting.FileSystemObject")
		drv = fso.GetDrive(drive)
		return drv.TotalSize
	except:
		return 0

def hdd_free(drive):
	'''
	Return the free space of a shared drive [bytes].
	Example:
		drive = r'\\servername\c$'
		print 'Free Space on %s = %d' % (drive, hdd_free(drive))
	'''
	import win32com.client
	try:
		fso = win32com.client.Dispatch("Scripting.FileSystemObject")
		drv = fso.GetDrive(drive)
		return drv.FreeSpace
	except:
		return 0

def __disk_c():
	import ctypes, os
	drive = os.getenv("SystemDrive")
	freeuser = ctypes.c_int64()
	total = ctypes.c_int64()
	free = ctypes.c_int64()
	ctypes.windll.kernel32.GetDiskFreeSpaceExW(drive, 
									ctypes.byref(freeuser), 
									ctypes.byref(total), 
									ctypes.byref(free))
	return freeuser.value

def __firefox_version():
	try:
		version = get_registry_value(
			"HKEY_LOCAL_MACHINE", 
			"SOFTWARE\\Mozilla\\Mozilla Firefox",
			"CurrentVersion")
		version = (u"Mozilla Firefox", version)
	except WindowsError:
		version = None
	return version

def __iexplore_version():
	try:
		version = get_registry_value(
			"HKEY_LOCAL_MACHINE", 
			"SOFTWARE\\Microsoft\\Internet Explorer",
			"Version")
		version = (u"Internet Explorer", version)
	except WindowsError:
		version = None
	return version

def __browsers():
	browsers = []
	firefox = firefox_version()
	if firefox:
		browsers.append(firefox)
	iexplore = iexplore_version()
	if iexplore:
		browsers.append(iexplore)

	return browsers

